package com.company.thread;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @description: 通过读写锁实现 一个简单缓存池的读写高并发
 * @author: ruoan
 * @date: 2020/12/9 15:21
 */
@Slf4j(topic = "MyResourcePool")
class MyResourcePool{

    // 定义缓存池，从里面实现读写
    private volatile Map<String, Object> map = new HashMap<>();

    private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    // 定义读方法
    public Object get(String key ){
        final Lock readLock = readWriteLock.readLock();
        readLock.lock();
        try{
            log.info(Thread.currentThread().getName()+"开始读取"+key);
            try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
            Object o = map.get(key);
            log.info(Thread.currentThread().getName()+"结束读取"+key);
            return o;
        } catch(Exception e) {
            e.printStackTrace();
        } finally {
            readLock.unlock();
        }
        return null;
    }

    // 定义写方法
    public void put(String key,Object value){
        final Lock writeLock = readWriteLock.writeLock();
        writeLock.lock();
        try{
            log.info(Thread.currentThread().getName()+"开始写入"+key);
            map.put(key, value);
            log.info(Thread.currentThread().getName()+"结束写入"+key);
        } catch(Exception e) {
            e.printStackTrace();
        } finally {
            writeLock.unlock();
        }


    }
    // 定义删除方法
    public void delete(String key){

        final Lock writeLock = readWriteLock.writeLock();
        writeLock.lock();
        try{
            if (StrUtil.isEmpty(key)) {
                map.clear();
            }else {
                log.info(Thread.currentThread().getName() + "开始移除" + key);
                Object remove = map.remove(key);
                log.info(Thread.currentThread().getName() + "结束移除" + key);
            }
        } catch(Exception e) {
            e.printStackTrace();
        } finally {
            writeLock.unlock();
        }



    }



}


@Slf4j(topic = "MyResourcePoolWithReadWriteLock")
public class MyResourcePoolWithReadWriteLock {


    public static void main(String[] args) {
        MyResourcePool myResourcePool = new MyResourcePool();


        // 10个线程写
        for(int i=0;i<10;i++){
            final int tmp = i;
            new Thread(() -> {
                myResourcePool.put(tmp+"",tmp+"");
            },String.valueOf(i)).start();
        }


        // 10个线程读
        for(int i=0;i<10;i++){
            final int tmp = i;
            new Thread(() -> {
                Object o = myResourcePool.get(tmp + "");
                log.info(Thread.currentThread().getName()+"获取到key"+tmp+"的值为："+o);
            },String.valueOf(i)).start();
        }

    }



}
